package com.junglone.gateway.admin.service;

import java.util.List;

import javax.annotation.Resource;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.junglone.gateway.admin.common.core.domain.PageDomain;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.junglone.gateway.admin.dao.MongoDao;
import com.junglone.gateway.admin.domain.MongoRoute;

/**
 * Description:
 *
 * @author junglone: <a href="mailto:cjlnzb@hotmail.com">cjlnzb@hotmail.com</a>
 * @since 2021/04/04 03:45
 */
@Service
public class MongoRouteService {

    private static final Logger LOGGER = LoggerFactory.getLogger(MongoRouteService.class);

    @Resource
    private MongoRouteEventService mongoRouteEventService;

    @Resource
    private MongoDao<MongoRoute> mongoRouteDao;

    /**
     * Description: 添加路由
     *
     * @param mongoRoute mongoRoute
     *
     * @return java.lang.String 新添加的路由 id
     *
     * @author junglone: <a href="mailto:cjlnzb@hotmail.com">cjlnzb@hotmail.com</a>
     * @since 2021/04/09 16:38
     */
    public String add(MongoRoute mongoRoute) {

        mongoRoute = mongoRouteDao.insert(mongoRoute);
        mongoRouteEventService.notifyChanged();

        return mongoRoute.getId();
    }

    /**
     * Description: 更新路由
     *
     * @param mongoRoute mongoRoute
     *
     * @return long 更新条数
     *
     * @author junglone: <a href="mailto:cjlnzb@hotmail.com">cjlnzb@hotmail.com</a>
     * @since 2021/04/09 16:45
     */
    public long update(MongoRoute mongoRoute) {

        long nResult = 0L;
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);

            Criteria criteria = Criteria.where("id").is(mongoRoute.getId());
            Query query = new Query();
            query.addCriteria(criteria);

            LOGGER.info("---- mongoRoute ==== {}", objectMapper.writeValueAsString(mongoRoute));

            ObjectNode jsonNodes;
            Update update;
            // 停用/启用操作不能修改排序
            if (-1 == mongoRoute.getOrder()) {

                jsonNodes = objectMapper.readValue(objectMapper.writeValueAsString(mongoRoute), ObjectNode.class);
                jsonNodes.remove("order");
                update = Update.fromDocument(Document.parse(jsonNodes.toString()));
            }
            else {

                update = Update.fromDocument(Document.parse(objectMapper.writeValueAsString(mongoRoute)));
            }
            update.currentDate("updateTime");

            LOGGER.info("---- update ==== {}", update);
            LOGGER.info("---- update ==== {}", objectMapper.writeValueAsString(update));

            UpdateResult updateResult = mongoRouteDao.update(query, update, MongoRoute.class);
            LOGGER.info("---- updateResult ==== {}", objectMapper.writeValueAsString(updateResult));

            mongoRouteEventService.notifyChanged();

            nResult = updateResult.getModifiedCount();
        }
        catch (Exception e) {
            LOGGER.error("Invoke update() happened Exception ==== {}", e.getMessage(), e);
        }

        return  nResult;
    }

    /**
     * Description: 删除路由
     *
     * @param strId routeId
     *
     * @return long 删除条数
     *
     * @author junglone: <a href="mailto:cjlnzb@hotmail.com">cjlnzb@hotmail.com</a>
     * @since 2021/04/14 12:39
     */
    public long delete(String strId) {

        try {

            Criteria criteria = Criteria.where("id").is(strId);
            Query query = new Query();
            query.addCriteria(criteria);
            DeleteResult deleteResult = mongoRouteDao.remove(query, MongoRoute.class);

            mongoRouteEventService.notifyChanged();

            return deleteResult.getDeletedCount();
        }
        catch (Exception e) {
            LOGGER.error("Invoke delete() happened Exception ==== {}", e.getMessage(), e);
        }

        return 0L;
    }

    /**
     * Description: 分页查询路由列表
     *
     * @param pageDomain pageable 分页信息, 包含当前页码和每页条数
     *
     * @return org.springframework.data.domain.Page<com.junglone.gateway.admin.route.MongoRoute>
     *
     * @author junglone: <a href="mailto:cjlnzb@hotmail.com">cjlnzb@hotmail.com</a>
     * @since 2021/04/12 17:54
     */
    public Page<MongoRoute> getRouteList(PageDomain pageDomain) {

        LOGGER.info("pageDomain ==== {}", pageDomain);

        Pageable pageable = PageRequest.of(pageDomain.getPageNum(), pageDomain.getPageSize(), pageDomain.getSort());

        LOGGER.info("pageable ==== {}", pageable);

        Query query = new Query();
        query.with(pageable);

        long lCount = mongoRouteDao.count(query, MongoRoute.class);
        LOGGER.info("lCount ==== {}", lCount);

        List<MongoRoute> mongoRouteList = mongoRouteDao.findAll(query, MongoRoute.class);
        Page<MongoRoute> mongoRoutePage = new PageImpl<>(mongoRouteList, pageable, lCount);
        LOGGER.info("mongoRoutePage ==== {}", mongoRoutePage);
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            LOGGER.info("writeValueAsString(mongoRoutePage) ==== {}", objectMapper.writeValueAsString(mongoRoutePage));
        }
        catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        return mongoRoutePage;
    }

    /**
     * Description: 根据路由 id 查询路由详细信息
     *
     * @param strId strId
     *
     * @return com.junglone.gateway.admin.route.MongoRoute
     *
     * @author junglone: <a href="mailto:cjlnzb@hotmail.com">cjlnzb@hotmail.com</a>
     * @since 2021/04/09 16:58
     */
    public MongoRoute getRouteById(String strId) {

        Criteria criteria = Criteria.where("id").is(strId);
        Query query = new Query();
        query.addCriteria(criteria);

        MongoRoute mongoRoute = mongoRouteDao.findOne(query, MongoRoute.class);

        ObjectMapper objectMapper = new ObjectMapper();
        try {
            LOGGER.info("mongoRoute ==== {}", objectMapper.writeValueAsString(mongoRoute));
        }
        catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        return mongoRoute;
    }

}
